//
//  BOLLIN.cpp
//  Chart
//
//  Created by CaoJun on 14-9-1.
//
//

#include "BOLLIN.h"


using namespace ytx;
using namespace std;


BOLLIN::BOLLIN(IndexConfig indexConfig):IndexData(indexConfig, 0)
{
    indexName = "BOLLIN";
    type = QuotationType::BOLLIN;
}

BOLLIN::~BOLLIN()
{

}

void BOLLIN::updateLastest(Quotation * data)
{
    int len = data->getDataLength();

    int n = para.value[0];
    int p = para.value[1];

    n = (int) Tools::between(para.range[0].first, para.range[0].second, n);
    p = (int) Tools::between(para.range[1].first, para.range[1].second, p);

    if (len < n){
        return;
    }


    vector<int> nList;

    nList.push_back(n);

    vector<double> MA = computeMA(data, nList, &KLineItem::close, len - n)[0];

    double MID;

    MID = computeStandardDeviation(transQuote(data, &ytx::KLineItem::close), n, len - 1);

    lineData[0].back() = MA.back() + MID * p;
    lineData[1].back() = MA.back();
    lineData[2].back() = MA.back() - MID * p;
}

void BOLLIN::calculate(Quotation * data)
{
    this->lineData.clear();

    int len = data->getDataLength();

    int n = para.value[0];
    int p = para.value[1];

    n = (int) Tools::between(para.range[0].first, para.range[0].second, n);
    p = (int) Tools::between(para.range[1].first, para.range[1].second, p);

    drawType = IndexDrawType::KIndex;

    vector<int> nList;

    nList.push_back(n);

    if (len < n){
        lineData.push_back(validation(len, len));
        lineData.push_back(validation(len, len));
        lineData.push_back(validation(len, len));
        return;
    }

    std::vector<double> MA = computeMA(data, nList, &KLineItem::close)[0];

    std::vector<double> MD = validation(n, len);

    std::vector<double> UP = validation(n, len);

    std::vector<double> DN = validation(n, len);

    std::vector<double> MID = validation(n, len);

    int i = n - 1;

    std::vector<double> close = transQuote(data, &ytx::KLineItem::close);

    while (i < len) {
        MD[i] = computeStandardDeviation(close, n, i);
//        sum = 0;
//        for (j = 0; j < n; j++){
//            sum += pow(data->kLineData[i - j].close - MA[i], 2);
//        }
//        MD[i] = sqrt(sum / (n) );
        i++;
    }

    i = n - 1;
    while (i < len) {
        MID[i] = MA[i];
        UP[i] = MID[i] + MD[i] * p;
        DN[i] = MID[i] - MD[i] * p;
        i++;
    }

    lineData.push_back(UP);
    lineData.push_back(MID);
    lineData.push_back(DN);

}


vector<vector<double> > BOLLIN::getOriginLineData()
{
    return this->originLineData;
}

void BOLLIN::setOriginLineData(vector<vector<double> > originLineData)
{
    this->originLineData = originLineData;
}

int BOLLIN::getDataLength() const
{
    return lineData.size() ? (int)lineData[0].size() : 0;
}

